package com.share.device.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.share.common.core.exception.ServiceException;
import com.share.common.security.utils.SecurityUtils;
import com.share.device.domain.Cabinet;
import com.share.device.domain.CabinetSlot;
import com.share.device.domain.CabinetType;
import com.share.device.domain.PowerBank;
import com.share.device.mapper.CabinetMapper;
import com.share.device.mapper.CabinetSlotMapper;
import com.share.device.mapper.CabinetTypeMapper;
import com.share.device.service.ICabinetService;
import com.share.device.service.IPowerBankService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
public class CabinetServiceImpl extends ServiceImpl<CabinetMapper, Cabinet> implements ICabinetService {

    @Autowired
    private CabinetMapper cabinetMapper;
    @Autowired
    private CabinetTypeMapper cabinetTypeMapper;
    @Autowired
    private CabinetSlotMapper cabinetSlotMapper;
    @Autowired
    private IPowerBankService powerBankService;

    @Override
    public List<Cabinet> selectCabinetList(Cabinet cabinet) {
        return cabinetMapper.selectCabinetList(cabinet);
    }

    /**
     * 新增柜机，需要设置柜机分类 外键
     * @param cabinet
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public Boolean saveCabinet(Cabinet cabinet) {

        //判断柜机编号是否已存在
        long count = this.count(new LambdaQueryWrapper<Cabinet>().eq(Cabinet::getCabinetNo, cabinet.getCabinetNo()));
        if (count > 0) {
            throw new ServiceException("该柜机编号已存在");
        }

            //根据 cabinet_type_id查找对应的柜机类型
            CabinetType cabinetType = cabinetTypeMapper.selectById(cabinet.getCabinetTypeId());

            //设置柜机的槽位数
            cabinet.setTotalSlots(cabinetType.getTotalSlots());
            cabinet.setFreeSlots(cabinetType.getTotalSlots());
            cabinet.setUsedSlots(0);
            cabinet.setAvailableNum(0);
            cabinet.setCreateTime(new Date());
//        cabinet.setCreateBy(SecurityUtils.getUsername());
            //新增柜机信息
            cabinetMapper.insert(cabinet);

            //将对应的槽位信息插入到slot表
            List<CabinetSlot> cabinetSlotList = new ArrayList<>();

            for(int i = 0;i<cabinet.getTotalSlots();i++){
                CabinetSlot cabinetSlot = new CabinetSlot();
                //设置属性
                cabinetSlot.setCabinetId(cabinet.getId());
                cabinetSlot.setSlotNo(i+1+"");
                cabinetSlot.setCreateTime(new Date());
    //            cabinet.setCreateBy(SecurityUtils.getUsername());

                cabinetSlotList.add(cabinetSlot);
            }

            //批量新增槽位
            cabinetSlotMapper.insertBatch(cabinetSlotList);


        return true;
    }

    //搜索未使用柜机 状态为 0
    @Override
    public List<Cabinet> selectNoUse(String keyword) {
        return cabinetMapper.selectNoUse(keyword);
    }

    //获取充电宝柜机全部详细信息 包括柜机中槽位以及对应充电宝信息
    @Override
    public Map<String, Object> getAllInfo(Long id) {
        // 查询柜机信息
        Cabinet cabinet = cabinetMapper.selectById(id);

        // 查询插槽信息 mp
        LambdaQueryWrapper<CabinetSlot> cabinetSlotLambdaQueryWrapper =
                new LambdaQueryWrapper<CabinetSlot>()
                .eq(CabinetSlot::getCabinetId,cabinet.getId());

        List<CabinetSlot> cabinetSlotList = cabinetSlotMapper.selectList(cabinetSlotLambdaQueryWrapper);

        // 获取可用充电宝id列表

        //获取对应槽位的充电宝id
        List<Long> powerBankIdList = cabinetSlotList.stream().filter(item -> null != item.getPowerBankId())
                .map(CabinetSlot::getPowerBankId).collect(Collectors.toList());

        if( !powerBankIdList.isEmpty()) {
            //根据充电宝id获取所有对应的充电宝
            List<PowerBank> powerBankList = powerBankService.listByIds(powerBankIdList);

            //创建map，键为充电宝id，值为对应充电宝
            Map<Long,PowerBank> powerBankIdToPowerBankMap = powerBankList.stream().
                    collect(Collectors.toMap(PowerBank::getId, PowerBank -> PowerBank));

            //将充电宝id和对应充电宝对应
            for (CabinetSlot cabinetSlot : cabinetSlotList) {
                cabinetSlot.setPowerBank(powerBankIdToPowerBankMap.get(cabinetSlot.getPowerBankId()));
            }
//            cabinetSlotList.forEach(item -> item.setPowerBank(powerBankIdToPowerBankMap.get(item.getPowerBankId())));
        }

        //将柜机信息、槽位信息以及充电宝信息以map返回
        Map<String, Object> result = Map.of("cabinet", cabinet, "cabinetSlotList", cabinetSlotList);

        return result;
    }

    //根据柜机编号查询柜机
    @Override
    public Cabinet getByCabinetNo(String cabinetNo) {
        LambdaQueryWrapper<Cabinet> wrapper = new LambdaQueryWrapper<Cabinet>().eq(Cabinet::getCabinetNo, cabinetNo);
        return cabinetMapper.selectOne(wrapper);
    }
}
